using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WMPLib;
using System.Threading;
using TempusFugate.TrendSetter.Utility.fb.tempusfugate.com;
using System.Diagnostics;
using System.Configuration;
using System.Reflection;
using System.IO;

namespace TempusFugate.TrendSetter.Utility
{
  public partial class frmMain : Form
  {

    ProcessWorker workerProcess;

    public frmMain()
    {
      InitializeComponent();
    } //frmMain

    private void btLoad_Click( object sender, EventArgs e )
    {

      workerProcess = new ProcessWorker();
      workerProcess.InitializeProcess += new StatusEventHandler( HandleInitialize );
      workerProcess.UpdateProcess += new StatusEventHandler( HandleUpdate );
      workerProcess.FinalizeProcess += new StatusEventHandler( HandleFinalize );
      workerProcess.ErrorProcess += new StatusEventHandler( HandleError );

      Thread threadPost = new Thread( new ThreadStart( workerProcess.DoPost ) );
      threadPost.Start();

    }  //btLoad_Click

    private void btFixUp_Click( object sender, EventArgs e )
    {

      workerProcess = new ProcessWorker();
      workerProcess.InitializeProcess += new StatusEventHandler( HandleInitialize );
      workerProcess.UpdateProcess += new StatusEventHandler( HandleUpdate );
      workerProcess.FinalizeProcess += new StatusEventHandler( HandleFinalize );
      workerProcess.ErrorProcess += new StatusEventHandler( HandleError );

      Thread threadFix = new Thread( new ThreadStart( workerProcess.DoFix ) );
      threadFix.Start();

    }//btFixUp_Click

    private void btStop_Click( object sender, EventArgs e )
    {
      workerProcess.Break = true;
    } //btStop_Click

    public class StatusEventArgs : EventArgs
    {
      private int numSteps = 0;

      public int NumSteps
      {
        get { return numSteps; }
        set { numSteps = value; }
      }
      private int currStep = 0;

      public int CurrStep
      {
        get { return currStep; }
        set { currStep = value; }
      }
      private string[] cells;

      public string[] Cells
      {
        get { return cells; }
        set { cells = value; }
      }

      private string message;

      public string Message
      {
        get { return message; }
        set { message = value; }
      }

    } //StatusEventArgs

    public delegate void StatusEventHandler( object sender, StatusEventArgs e );

    public class ProcessWorker
    {
      private volatile bool bBreak = false;
      public bool Break
      {
        get { return bBreak; }
        set { bBreak = value; }
      }

      public event StatusEventHandler InitializeProcess;
      public event StatusEventHandler UpdateProcess;
      public event StatusEventHandler FinalizeProcess;
      public event StatusEventHandler ErrorProcess;
      protected virtual void OnInitializeProcess( StatusEventArgs e )
      {
        if ( InitializeProcess != null )
          InitializeProcess( this, e );
      }
      protected virtual void OnUpdateProcess( StatusEventArgs e )
      {
        if ( UpdateProcess != null )
          UpdateProcess( this, e );
      }
      protected virtual void OnFinalizeProcess( StatusEventArgs e )
      {
        if ( FinalizeProcess != null )
          FinalizeProcess( this, e );
      }
      protected virtual void OnErrorProcess( StatusEventArgs e )
      {
        if ( ErrorProcess != null )
          ErrorProcess( this, e );
      }

      public void DoPost()
      {

        Incoming upload = null;
        WindowsMediaPlayer wmp = null;
        IWMPPlaylist playlist = null;
        IWMPMedia media = null;
        int numItems = 0;
        StatusEventArgs e = null;
        bool success = false;
        string response = null;
        string[] hdrs = null;
        string[] cells = null;
        string[][] attribs = null;
        int numAttribs = 0;
        int itm = 0;
        string path = "";
        int stepSize = 10;
        bool traceEnabled = true;

        try
        {
          stepSize = int.Parse( ConfigurationManager.AppSettings[ "stepsize" ] );
        }
        catch { }

        try
        {
          traceEnabled = bool.Parse( ConfigurationManager.AppSettings[ "tracingenabled" ] );
        }
        catch { }

        try
        {
          path = ConfigurationManager.AppSettings[ "tracingpath" ];
        }
        catch { }

        if ( ( path == null ) || ( path.Length == 0 ) )
        {
          path = System.Windows.Forms.Application.StartupPath;
          if ( path.Length > 1 )
          {
            if ( path.Substring( path.Length - 1, 1 ) != "\\" ) { path += "\\"; }
          }
          path += "trace.log";
        }

        try
        {
          upload = new Incoming();
          wmp = new WindowsMediaPlayer();
          playlist = wmp.mediaCollection.getAll();
        }
        catch ( Exception init )
        {
          Trace.WriteLine( "Error Loading Resources: " + init.ToString() );
        }

        try
        {
          numItems = playlist.count;

          e = new StatusEventArgs();
          e.CurrStep = 0;
          e.NumSteps = numItems;

          hdrs = new string[ 5 ];
          hdrs[ 0 ] = "Track";
          hdrs[ 1 ] = "Title";
          hdrs[ 2 ] = "AlbumArtist";
          hdrs[ 3 ] = "AlbumTitle";
          hdrs[ 4 ] = "Author";

          e.Cells = hdrs;
          e.Message = "Initializing...";
          OnInitializeProcess( e );

          for ( itm = 0; itm < numItems; itm++ )
          {

            media = ( IWMPMedia ) playlist.get_Item( itm );

            cells = new string[ 5 ];
            cells[ 0 ] = media.getItemInfo( "WM/TrackNumber" );
            cells[ 1 ] = media.getItemInfo( "Title" );
            cells[ 2 ] = media.getItemInfo( "WM/AlbumArtist" );
            cells[ 3 ] = media.getItemInfo( "WM/AlbumTitle" );
            cells[ 4 ] = media.getItemInfo( "Author" );

            numAttribs = media.attributeCount;
            attribs = new string[ 2 ][];
            attribs[ 0 ] = new string[ numAttribs ];
            attribs[ 1 ] = new string[ numAttribs ];
            for ( int pos = 0; pos < numAttribs; pos++ )
            {
              string attribName = media.getAttributeName( pos );
              attribs[ 0 ][ pos ] = attribName;
              attribs[ 1 ][ pos ] = media.getItemInfo( attribName );
            }

            try
            {
              //use fields to make a post
              success = upload.PostMedia( 1, attribs, out response );
              if ( success )
              {
                cells = null;
              }
              else
              {
                if ( traceEnabled )
                {
                  using ( StreamWriter txt = new StreamWriter( path, true ) )
                  {
                    txt.WriteLine( "--BEG---------------" );
                    txt.WriteLine( "Response: " + response );
                    for ( int pos = 0; pos < numAttribs; pos++ )
                    {
                      txt.WriteLine( attribs[ 0 ][ pos ] + ":" + attribs[ 1 ][ pos ] );
                    }
                    txt.WriteLine( "--END---------------" );
                  } //using
                }
                throw new Exception( response );
              }
            }
            catch ( Exception pst )
            {
              using ( StreamWriter txt = new StreamWriter( path, true ) )
              {
                txt.WriteLine( "--BEG-ERR--------------" );
                txt.WriteLine( "Response: " + response );
                for ( int pos = 0; pos < numAttribs; pos++ )
                {
                  txt.WriteLine( attribs[ 0 ][ pos ] + ":" + attribs[ 1 ][ pos ] );
                }
                txt.WriteLine( "--END-ERR--------------" );
              } //using
              e.CurrStep = itm;
              e.Cells = cells;
              e.Message = pst.Message;
              OnErrorProcess( e );
            }

            if ( bBreak ) { break; };

            //TODO: should be user prefence value
            if ( ( ( itm % stepSize ) == 0 ) || ( !success ) )
            {
              e.CurrStep = itm;
              e.Cells = cells;
              e.Message = string.Format( "Processing {0} of {1}", itm, numItems );
              OnUpdateProcess( e );
              if ( bBreak ) { break; };
            }

          } //for

          e.CurrStep = numItems;
          e.Cells = null;
          OnFinalizeProcess( e );
        }
        catch ( Exception err )
        {
          e.Cells = cells;
          e.Message = err.Message;
          OnErrorProcess( e );
          OnFinalizeProcess( e );
        }

      } //DoPost

      public void DoFix()
      {

        WindowsMediaPlayer wmp = null;
        IWMPPlaylist playlist = null;
        IWMPMedia media;
        int numItems = 0;
        StatusEventArgs e = null;

        try
        {
          wmp = new WindowsMediaPlayer();
          playlist = wmp.mediaCollection.getAll();

          numItems = playlist.count;

          e = new StatusEventArgs();
          e.CurrStep = 0;
          e.NumSteps = numItems;

          string[] hdrs = new string[ 6 ];
          hdrs[ 0 ] = "Track";
          hdrs[ 1 ] = "Title";
          hdrs[ 2 ] = "AlbumArtist";
          hdrs[ 3 ] = "AlbumTitle";
          hdrs[ 4 ] = "Author";
          hdrs[ 5 ] = "Copyright";

          e.Cells = hdrs;
          e.Message = "Initializing...";
          OnInitializeProcess( e );

          for ( int i = 0; i < numItems; i++ )
          {

            media = ( IWMPMedia ) playlist.get_Item( i );

            string[] cells = new string[ 7 ];

            cells[ 6 ] = media.getItemInfo( "Description" );
            if ( cells[ 6 ].Contains( "torrent" ) )
            {
              cells[ 0 ] = media.getItemInfo( "WM/TrackNumber" );
              cells[ 1 ] = media.getItemInfo( "Title" );
              cells[ 2 ] = media.getItemInfo( "WM/AlbumArtist" );
              cells[ 3 ] = media.getItemInfo( "WM/AlbumTitle" );
              cells[ 4 ] = media.getItemInfo( "Author" );
              cells[ 5 ] = media.getItemInfo( "Copyright" );
              media.setItemInfo( "Description", "a b e r g m a n n e f f e c t" );
              e.CurrStep = i;
              e.Cells = cells;
              e.Message = string.Format( "Processing {0} of {1}", i, numItems );
              OnUpdateProcess( e );

              if ( bBreak ) { break; };

            } //contains torrent

            if ( ( i % 50 ) == 0 )
            {
              e.CurrStep = i;
              e.Cells = null;
              e.Message = string.Format( "Processing {0} of {1}", i, numItems );
              OnUpdateProcess( e );
              if ( bBreak ) { break; };
            }

          } //for

          e.CurrStep = numItems;
          e.Cells = null;
          e.Message = "Ready";
          OnFinalizeProcess( e );
        }
        catch ( Exception err )
        {
          e.Cells = null;
          e.Message = "Error:" + err.ToString();
          OnErrorProcess( e );
        }

      } //DoFix

    } //public class FixWorker

    private delegate void HandleDelegate( object sender, StatusEventArgs e );

    public void HandleInitialize( object sender, StatusEventArgs e )
    {
      if ( this.InvokeRequired )
      {
        this.Invoke( new HandleDelegate( HandleInitialize ), new object[] { sender, e } );
      }
      else
      {

        try
        {
          this.btLoadiTunes.Enabled = false;
          this.btLoadWMP.Enabled = false;
          this.btFixUp.Enabled = false;
          this.btStop.Enabled = true;
          this.pbStatus.Visible = true;

          this.grdMedia.Rows.Clear();
          this.grdMedia.ColumnCount = e.Cells.Length;

          for ( int i = 0; i < e.Cells.Length; i++ )
          {
            this.grdMedia.Columns[ i ].HeaderText = e.Cells[ i ];
          }

          this.grdMedia.Refresh();

          this.pbStatus.Minimum = 0;
          this.pbStatus.Maximum = e.NumSteps;
          this.pbStatus.Step = 1;

          this.lblStatus.Text = e.Message;
        }
        catch ( Exception grd )
        {
          this.lblStatus.Text = "Error: " + grd.ToString();
        }

      } //invokerequired

    } //handleinitialize

    public void HandleUpdate( object sender, StatusEventArgs e )
    {
      if ( this.InvokeRequired )
      {
        this.Invoke( new HandleDelegate( HandleUpdate ), new object[] { sender, e } );
      }
      else
      {
        if ( e.Cells != null )
        {
          this.grdMedia.Rows.Add( e.Cells );
          this.grdMedia.Refresh();
        }
        this.lblStatus.Text = e.Message;
        this.pbStatus.Value = e.CurrStep;
      } //invokerequired

    } //handleupdate

    public void HandleFinalize( object sender, StatusEventArgs e )
    {
      if ( this.InvokeRequired )
      {
        this.Invoke( new HandleDelegate( HandleFinalize ), new object[] { sender, e } );
      }
      else
      {

        this.btLoadiTunes.Enabled = true;
        this.btLoadWMP.Enabled = true;
        this.btFixUp.Enabled = true;
        this.btStop.Enabled = false;
        this.pbStatus.Visible = false;
        this.lblStatus.Text = "Ready";

      } //invokerequired

    } //handlefinalize

    public void HandleError( object sender, StatusEventArgs e )
    {
      string errorMessage = string.Format( "Error Processing {0} of {1}", e.CurrStep, e.NumSteps ) + e.Message;

      if ( this.InvokeRequired )
      {
        this.Invoke( new HandleDelegate( HandleError ), new object[] { sender, e } );
      }
      else
      {

        if ( e.Cells != null )
        {
          e.Cells[ 2 ] = errorMessage;
          this.grdMedia.Rows.Add( e.Cells );
          this.grdMedia.Refresh();
        }

        this.lblStatus.Text = errorMessage;

      } //invokerequired

    } //handlefinalize

  } //class frmMain

}

/*
cells[ 7 ] = media.getItemInfo( "DisplayArtist" );
cells[ 8 ] = media.getItemInfo( "WM/Category" );
cells[ 9 ] = media.getItemInfo( "WM/Composer" );
cells[ 10 ] = media.getItemInfo( "WM/Conductor" );
cells[ 11 ] = media.getItemInfo( "WM/Genre" );
cells[ 12 ] = media.getItemInfo( "WM/Lyrics" );
cells[ 13 ] = media.getItemInfo( "WM/Mood" );
cells[ 14 ] = media.getItemInfo( "WM/Provider" );
cells[ 15 ] = media.getItemInfo( "WM/ProviderRating" );
cells[ 16 ] = media.getItemInfo( "WM/ProviderStyle" );
cells[ 17 ] = media.getItemInfo( "WM/Publisher" );
cells[ 18 ] = media.getItemInfo( "WM/SubTitle" );
cells[ 19 ] = media.getItemInfo( "WM/Writer" );
cells[ 20 ] = media.getItemInfo( "WM/Year" );
*/

//  cells[ 0 ] = media.getItemInfo( "AlbumID" );
//  cells[ 1 ] = media.getItemInfo( "AlbumIDAlbumArtist" );
//  cells[ 2 ] = media.getItemInfo( "Author" );
//  cells[ 3 ] = media.getItemInfo( "Copyright" );
//  cells[ 4 ] = media.getItemInfo( "Description" );
//  cells[ 5 ] = media.getItemInfo( "DisplayArtist" );
//  cells[ 6 ] = media.getItemInfo( "MoreInfo" );
//  cells[ 7 ] = media.getItemInfo( "ProviderURL" );
//  cells[ 8 ] = media.getItemInfo( "SourceURL" );
//  cells[ 9 ] = media.getItemInfo( "Title" );
//  cells[ 10 ] = media.getItemInfo( "UserEffectiveRating" );
//  cells[ 11 ] = media.getItemInfo( "UserLastPlayedTime" );
//  cells[ 12 ] = media.getItemInfo( "UserPlayCount" );
//  cells[ 13 ] = media.getItemInfo( "UserRating" );
//  cells[ 14 ] = media.getItemInfo( "UserServiceRating" );
//  cells[ 15 ] = media.getItemInfo( "WM/AlbumArtist" );
//  cells[ 16 ] = media.getItemInfo( "WM/AlbumTitle" );
//  cells[ 17 ] = media.getItemInfo( "WM/Category" );
//  cells[ 18 ] = media.getItemInfo( "WM/Composer" );
//  cells[ 19 ] = media.getItemInfo( "WM/Conductor" );
//  cells[ 20 ] = media.getItemInfo( "WM/Genre" );
//  cells[ 21 ] = media.getItemInfo( "WM/GenreID" );
//  cells[ 22 ] = media.getItemInfo( "WM/Lyrics" );
//  cells[ 23 ] = media.getItemInfo( "WM/Mood" );
//  cells[ 24 ] = media.getItemInfo( "WM/Provider" );
//  cells[ 25 ] = media.getItemInfo( "WM/ProviderRating" );
//  cells[ 26 ] = media.getItemInfo( "WM/ProviderStyle" );
//  cells[ 27 ] = media.getItemInfo( "WM/Publisher" );
//  cells[ 28 ] = media.getItemInfo( "WM/SubTitle" );
//  cells[ 29 ] = media.getItemInfo( "WM/TrackNumber" );
//  cells[ 30 ] = media.getItemInfo( "WM/UniqueFileIdentifier" );
//  cells[ 31 ] = media.getItemInfo( "WM/WMCollectionGroupID" );
//  cells[ 32 ] = media.getItemInfo( "WM/WMCollectionID" );
//  cells[ 33 ] = media.getItemInfo( "WM/WMContentID" );
//  cells[ 34 ] = media.getItemInfo( "WM/Writer" );
//  cells[ 35 ] = media.getItemInfo( "WM/Year" );
//  //cells[ 36 ] = media.getItemInfo( "AlbumArtist" );

/*
AlbumID
AlbumIDAlbumArtist
Author
Copyright
Description
DisplayArtist
MoreInfo
ProviderURL
SourceURL
Title
UserEffectiveRating
UserLastPlayedTime
UserPlayCount
UserRating
UserServiceRating
WM/AlbumArtist
WM/AlbumTitle
WM/Category
WM/Composer
WM/Conductor
WM/Genre
WM/GenreID
WM/Lyrics
WM/Mood
WM/Provider
WM/ProviderRating
WM/ProviderStyle
WM/Publisher
WM/SubTitle
WM/TrackNumber
WM/UniqueFileIdentifier
WM/WMCollectionGroupID
WM/WMCollectionID
WM/WMContentID
WM/Writer
WM/Year
*/